package com.xs.gis.cover.coverImpl;

import com.xs.gis.cover.FileCover;
import com.xs.gis.cover.util.CoverFactory;
import com.xs.gis.domain.geojson.*;
import com.xs.gis.util.CRSUtils;
import com.xs.gis.util.JacksonUtil;
import com.csvreader.CsvReader;
import com.csvreader.CsvWriter;
import org.apache.commons.lang3.StringUtils;
import org.geotools.geojson.geom.GeometryJSON;
import org.locationtech.jts.geom.Geometry;
import org.locationtech.jts.io.ParseException;

import java.io.IOException;
import java.math.BigDecimal;
import java.nio.charset.StandardCharsets;
import java.util.*;

/**
 * @author w
 */
public class CsvCover implements FileCover {

    @Override
    public String featureToFile(GeoJsonFeature feature, String filePath) throws IOException {
        // 第一参数：新生成文件的路径 第二个参数：分隔符（不懂仔细查看引用百度百科的那段话） 第三个参数：字符集
        CsvWriter csvWriter = new CsvWriter(filePath, ',', StandardCharsets.UTF_8);

        List<GeoFeature> features = feature.getFeatures();
        StringBuffer headers = new StringBuffer();

//        写入表头
        try {
            GeoFeature geoFeature = features.get(0);
            geoFeature.getProperties().forEach((k, v) ->  {
                if(StringUtils.isBlank(headers)){
                    headers.append(k);
                }else {
                    headers.append(",").append(k);
                }
            });
            headers.append(",").append("Geometry");
            csvWriter.writeRecord(headers.toString().split(","));
            GeoJsonCover geoJsonCover = CoverFactory.buildGeoJsonCover();
            WktCover wktCover = CoverFactory.buildWktCover();
//        写入内容
            for (GeoFeature geoFeatureItem : features) {
                StringBuffer content = new StringBuffer();
                Map<String, Object> properties = geoFeatureItem.getProperties();
                properties.forEach((k,v) -> {
                    if(StringUtils.isBlank(content)){
                        content.append(v);
                    }else {
                        content.append("\n").append(v);
                    }
                });
                String jsonString = JacksonUtil.toJsonString(geoFeatureItem.getGeometry());
                Geometry geometry = geoJsonCover.dataToGeometry(jsonString);
                String geometryString = wktCover.geometryToData(geometry);
                content.append("\n").append(geometryString);
                csvWriter.writeRecord(content.toString().split("\n"));
            }
        } catch (ParseException e) {
            throw new RuntimeException(e);
        } finally {
            csvWriter.close();
        }
        return filePath;
    }

    @Override
    public GeoJsonFeature fileToFeature(String filePath) throws IOException {
        CsvReader csvReader = new CsvReader(filePath, ',', StandardCharsets.UTF_8);
        csvReader.readHeaders();
        List<GeoFeature> features = new ArrayList<>();
        GeoJsonFeature geoJsonFeature = new GeoJsonFeature();
        String tapeNumber = new String();
        try {
            while (csvReader.readRecord()) {
                Map<String, Object> properties = new HashMap<>();
                GeoFeature geoFeature = new GeoFeature();
                String[] values = csvReader.getValues();
                for (int i = 0; i < values.length; i++) {
                    String header = csvReader.getHeader(i);
                    if("Geometry".equalsIgnoreCase(header) || "geom".equalsIgnoreCase(header)){
                        WktCover wktCover = CoverFactory.buildWktCover();
                        Geometry geometry = wktCover.dataToGeometry(values[i]);
                        String x = new BigDecimal(geometry.getCoordinate().getX()).toString();
                        tapeNumber = x.substring(0,2);
                        GeometryJSON g = new GeometryJSON(15);
                        String geoJSON = g.toString(geometry);
                        geoFeature.setGeometry(JacksonUtil.toObject(geoJSON, BaseGeometry.class));
                    }else {
                        properties.put(header,values[i]);
                    }
                    geoFeature.setProperties(properties);
                    geoFeature.setType("Feature");
                }
                features.add(geoFeature);
            }
            String epsgCode = CRSUtils.getCRSByUTM(CRSUtils.CGCS2000, tapeNumber);
            GeoCrs geoCrs = new GeoCrs();
            GeoCrsProperties geoCrsProperties = new GeoCrsProperties();
            geoCrsProperties.setName(epsgCode);
            geoCrs.setType("name");
            geoCrs.setProperties(geoCrsProperties);
            geoJsonFeature.setCrs(geoCrs);
            geoJsonFeature.setType("FeatureCollection");
            geoJsonFeature.setFeatures(features);
        } catch (ParseException e) {
            throw new RuntimeException(e);
        }
        return geoJsonFeature;
    }
}
